package com.acme.team02.chat.client;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Client {

	private static final int PORT_NUMBER = 2013;
	private static String serverName = "localhost";
	private static Socket requestSocket;
	private static PrintWriter out;
	private static BufferedReader in;

	private static Logger logger = Logger.getLogger("clientLogger");

	private static class Listener implements Runnable {

		private BufferedReader in;
		private String serverResponse = "";

		public Listener(BufferedReader in) {
			this.in = in;
			try {
				logger.addHandler(new FileHandler("clientLog.txt"));
			} catch (SecurityException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		@Override
		public void run() {
			while (true) {
				try {
					serverResponse = in.readLine();
					if (serverResponse != null) {
						for (String substring : serverResponse.split("\\\\n")) {
							System.out.println(substring);
						}
					}

				} catch (IOException e) {
					System.out.println("Server died");
					logger.log(Level.WARNING, "Server died\n" + e);
					break;
				}
			}
		}

	}

	private static class Sender implements Runnable {

		private PrintWriter out;
		private String userMessage = "";

		public Sender(PrintWriter out) {
			this.out = out;
		}

		@Override
		public void run() {
			BufferedReader userInputStream = new BufferedReader(
					new InputStreamReader(System.in));
			while (true) {
				try {
					// console input:
					userMessage = userInputStream.readLine();
				} catch (IOException e) {
					System.out.println("Console input failed.");
					logger.log(Level.WARNING, "Console input failed.\n" + e);
				}
				sendMessage(userMessage);
			}
			// out.close();

		}

		void sendMessage(final String msg) {
			out.println(msg);
		}

	}

	public static void main(final String args[]) {
		Thread senderThread = null;
		parseArgs(args);

		try {
			connect();
			Thread listenThread = new Thread(new Listener(in));
			listenThread.start();
			senderThread = new Thread(new Sender(out));
			senderThread.start();
			listenThread.join();
		} catch (UnknownHostException unknownHost) {
			logger.log(Level.WARNING,
					"You are trying to connect to an unknown host!"
							+ unknownHost);
			System.err.println("You are trying to connect to an unknown host!");
		} catch (IOException ioException) {
			logger.log(Level.WARNING, "Connection lost" + ioException);
			System.out.println("Connection lost");
		} catch (InterruptedException e) {
			logger.log(Level.WARNING, "worker dead" + e);
			System.out.println("worker dead");
		} finally {
			closeResources();
			senderThread.interrupt();
		}
	}

	private static void closeResources() {
		try {
			System.out.println("Close connection");
			if (in != null) {
				in.close();
			}
			if (out != null) {
				out.close();
			}
			if (requestSocket != null) {
				requestSocket.close();
			}
		} catch (IOException ioException) {
			logger.log(Level.WARNING, "Connection close failed." + ioException);
			System.out.println("Connection close failed.");
		}
	}

	private static void connect() throws UnknownHostException, IOException {
		// 1. creating a socket to connect to the server
		requestSocket = new Socket(serverName, PORT_NUMBER);
		System.out.println("Connected to server");
		// 2. get Input and Output streams
		out = new PrintWriter(requestSocket.getOutputStream(), true);
		in = new BufferedReader(new InputStreamReader(
				requestSocket.getInputStream()));
	}

	private static void parseArgs(final String[] args) {
		if (args.length > 1) {
			if ("-host".equals(args[0])) {
				serverName = args[1];
			} else {
				serverName = "localhost";
			}

		}
	}

}
